﻿using System;
using System.Collections.ObjectModel;
using System.Threading;
using System.Windows;
using Loki.UI.Wpf.Resources;
using Loki.Utils;

namespace Loki.UI.Wpf
{
    public class BootStrapper : Application, IPlatform
    {
        #region Log

        private ILog _Log = null;

        /// <summary>
        /// Gets the logger.
        /// </summary>
        /// <value>The logger.</value>
        protected ILog Log
        {
            get
            {
                if (_Log == null)
                {
                    Interlocked.CompareExchange(ref _Log, ToolKit.Logger.GetLog(this.GetType().Name), null);
                }

                return _Log;
            }
        }

        #endregion Log

        private ITemplatingEngine _Templates;

        private IThreadingContext uiContext;

        public BootStrapper()
            : base()
        {
            ViewModels = new ObservableCollection<IViewModel>();
            _Templates = new WindsorWPFEngine();
            uiContext = new WpfThreadingContext();
        }

        public object MainObject
        {
            get
            {
                throw new NotImplementedException();
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public IView MainView
        {
            get
            {
                return MainWindow as IView;
            }

            set
            {
                MainWindow = value as Window;
            }
        }

        public ISignalManager Signals
        {
            get { throw new NotImplementedException(); }
        }

        public virtual ITemplatingEngine Templates
        {
            get { return _Templates; }
        }

        public IThreadingContext Threading
        {
            get
            {
                return uiContext;
            }
        }

        /// <summary>
        /// Gets the view models.
        /// </summary>
        public ObservableCollection<IViewModel> ViewModels
        {
            get;
            private set;
        }

        #region Properties

        public string ThemeName { get; set; }

        #endregion Properties

        #region Disposable

        ~BootStrapper()
        {
            Dispose(false);
        }

        /// <summary>
        /// Releases all resources used by an instance of the <see cref="BootStrapperWPF" /> class.
        /// </summary>
        /// <remarks>
        /// This method calls the virtual <see cref="Dispose(bool)" /> method, passing in
        /// <strong>true</strong>, and then suppresses finalization of the instance.
        /// </remarks>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Releases the unmanaged resources used by an instance of the
        /// <see cref="BootStrapperWPF" /> class and optionally releases the managed resources.
        /// </summary>
        /// <param name="P_Disposing">Sets <strong>true</strong> to release both managed and
        /// unmanaged resources; <strong>false</strong> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool P_Disposing)
        {
            ToolKit.Context.Dispose();
        }

        #endregion Disposable

        public new IWindowManager Windows
        {
            get { throw new NotImplementedException(); }
        }

        public void ApplicationExit()
        {
            Dispose();

            Log.Info(LogStrings.BootStrapper_ApplicationExit);
            Application.Current.Shutdown();
        }

        #region LastChanceError

        public event EventHandler<ExceptionEventArgs> LastChanceError;

        protected virtual void OnLastChanceError(ExceptionEventArgs e)
        {
            EventHandler<ExceptionEventArgs> L_Handler = LastChanceError;

            if (L_Handler != null)
            {
                L_Handler(this, e);
            }
        }

        #endregion LastChanceError

        public void Error(Exception P_Exception, bool P_Imperative)
        {
            LokiException L_Ex = P_Exception as LokiException;
            if (L_Ex != null)
            {
                ErrorMessageBox.Show(L_Ex, P_Imperative);
            }
            else
            {
                ErrorMessageBox.Show(ToolKit.Errors.BuildError<LokiException>(ErrorMessages.Application_UnhandledException, Log, P_Exception), P_Imperative);
            }
        }

        public void Message(string P_Message)
        {
            MessageBoxes.Message(P_Message);
        }

        public void Warning(string P_Warning)
        {
            MessageBoxes.Warning(P_Warning);
        }
    }
}